﻿#include "libcomm.h"

#define YEAR ((((__DATE__ [7] - '0') * 10 + (__DATE__ [8] - '0')) * 10 \
    + (__DATE__ [9] - '0')) * 10 + (__DATE__ [10] - '0'))
#define MONTH (__DATE__ [2] == 'n' ? (__DATE__ [1] == 'a' ? 0 : 5)  \
    : __DATE__ [2] == 'b' ? 1 \
    : __DATE__ [2] == 'r' ? (__DATE__ [0] == 'M' ? 2 : 3) \
    : __DATE__ [2] == 'y' ? 4 \
    : __DATE__ [2] == 'l' ? 6 \
    : __DATE__ [2] == 'g' ? 7 \
    : __DATE__ [2] == 'p' ? 8 \
    : __DATE__ [2] == 't' ? 9 \
    : __DATE__ [2] == 'v' ? 10 : 11)
#define DAY ((__DATE__ [4] == ' ' ? 0 : __DATE__ [4] - '0') * 10 \
    + (__DATE__ [5] - '0'))
#define DATE_AS_INT (((YEAR - 2000) * 12 + MONTH) * 31 + DAY)
 

const char* common_version()
{
	static String version(256);
	version.sprintf("%s_(%d-%02d-%02d %s)", COMM_VERSION, YEAR, MONTH+1, DAY, __TIME__);

#if (COMM_FEATURE_STDLIST==1)
	version.strcat("_STDLIST");
#endif
#if (COMM_FEATURE_REGEX==1)
	version.strcat("_REGEX");
#endif
#if (COMM_FEATURE_CURL==1)
	version.strcat("_CURL");
#endif
#if (COMM_FEATURE_LIBEVENT==1)
	version.strcat("_LIBEVENT");
#endif
#if (COMM_FEATURE_SSL==1)
	version.strcat("_SSL");
#endif
	return version;
}


void common_dumpstack(int signo, FILE* stream)
{
	if(NULL != stream)
	{
		fprintf(stream,"%s",StackTracer::TraceStack().get());
	}
	else
	{
		common_log(MYLIB_LOG_ERR,"%s",StackTracer::TraceStack().get());
	}
}

// could not invoking any log function.
//
void common_log(int level, const char* format, ...)
{
	va_list args;
	va_start(args, format);
	Log::Instance()->VWrite(level,format,args);
	va_end(args);
	
}

void common_log_level(int level)
{
	Log::Instance()->SetLevel(level);
}

//////////////////////////////////////////////////////////////////////////

#ifdef COMM_MSVC
static int _G_LOG_UTF8_ENABLE = 0;
void common_log_utf8_enable(int enable)
{
	_G_LOG_UTF8_ENABLE = enable ? 1 : 0;
}
int common_log_utf8_is_enable()
{
	return _G_LOG_UTF8_ENABLE;
}
static char* common_utf8(const char* gb2312)
{
	if (NULL == gb2312) return NULL;
	int len = MultiByteToWideChar(CP_ACP, 0, gb2312, -1, NULL, 0);
	wchar_t* wstr = new wchar_t[len + 1];
	memset(wstr, 0, len + 1);
	MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wstr, len);
	len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
	char* str = new char[len + 1];
	memset(str, 0, len + 1);
	WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
	if (wstr) delete[] wstr;
	return str;
}

CommErrorString::CommErrorString(DWORD errnum) :m_lpMsgBuf(NULL) {
	LPVOID lpMsgBuf = NULL;
	FormatMessageA(
		FORMAT_MESSAGE_ALLOCATE_BUFFER |
		FORMAT_MESSAGE_FROM_SYSTEM |
		FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL,
		errnum,
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
		(LPSTR)&lpMsgBuf,
		0,
		NULL
	);
	if (NULL != lpMsgBuf)
	{
		if (_G_LOG_UTF8_ENABLE)
		{
			m_lpMsgBuf = common_utf8((char*)lpMsgBuf);
			LocalFree(lpMsgBuf);
		}
		else
		{
			m_lpMsgBuf = lpMsgBuf;
		}
	}
}
CommErrorString::~CommErrorString() 
{ 
	if (NULL != m_lpMsgBuf) 
	{ 
		if (_G_LOG_UTF8_ENABLE)
		{
			char* lpMsgBuf = (char*)m_lpMsgBuf;
			delete[] lpMsgBuf;
		}
		else
		{
			LocalFree(m_lpMsgBuf);
		}
		m_lpMsgBuf = NULL;
	} 
}
CommErrorString::operator char*() const { return (char*)m_lpMsgBuf; }

#endif



